import json
from urllib.request import urlopen
from aliyunsdkcore.client import AcsClient
from aliyunsdkalidns.request.v20150109.AddDomainRecordRequest import AddDomainRecordRequest
from aliyunsdkalidns.request.v20150109.UpdateDomainRecordRequest import UpdateDomainRecordRequest
from aliyunsdkalidns.request.v20150109.DeleteSubDomainRecordsRequest import DeleteSubDomainRecordsRequest
from aliyunsdkalidns.request.v20150109.DescribeSubDomainRecordsRequest import DescribeSubDomainRecordsRequest


class dns:
    def __init__(self, Domain, Ali_KeyId, Ali_Secret):
        """
        :param domain: 主域名
        """
        self.ipv4_flag = 1
        self.ipv6_flag = 0
        self.domain = Domain
        self.ali_accessKeyId = Ali_KeyId
        self.ali_accessSecret = Ali_Secret
        self.client = AcsClient(self.ali_accessKeyId, self.ali_accessSecret, 'cn-hangzhou')

    def update(self, RecordId, RR, Type, Value):  # 修改域名解析记录
        global response
        request = UpdateDomainRecordRequest()
        request.set_accept_format('json')
        request.set_RecordId(RecordId)
        request.set_RR(RR)
        request.set_Type(Type)
        request.set_Value(Value)
        response = self.client.do_action_with_exception(request)

    def add(self, DomainName, RR, Type, Value):  # 添加新的域名解析记录
        global response
        request = AddDomainRecordRequest()
        request.set_accept_format('json')
        request.set_DomainName(DomainName)
        request.set_RR(RR)
        request.set_Type(Type)
        request.set_Value(Value)
        response = self.client.do_action_with_exception(request)

    def ipv4_dns(self, name):
        """
        :param name: 解析到子域名 例：www
        :return:
        """
        global response

        if self.ipv4_flag == 1:
            request = DescribeSubDomainRecordsRequest()
            request.set_accept_format('json')
            request.set_DomainName(self.domain)
            request.set_SubDomain(name + '.' + self.domain)
            request.set_Type("A")
            response = self.client.do_action_with_exception(request)
            domain_list = json.loads(response)

            try:
                ip = urlopen('https://api-ipv4.ip.sb/ip').read()
                ipv4 = str(ip, encoding='utf-8')
            except Exception:
                ip = urlopen('http://httpbin.org/ip').read()
                ipv4 = json.loads(ip)['origin']

            if domain_list['TotalCount'] == 0:
                self.add(self.domain, name, "A", ipv4)
                print("获取到IPv4地址：%s" % ipv4)
                print("新增域名解析成功")

            elif domain_list['TotalCount'] == 1:
                if domain_list['DomainRecords']['Record'][0]['Value'].strip() != ipv4.strip():
                    self.update(domain_list['DomainRecords']['Record'][0]['RecordId'], name, "A", ipv4)
                    print("获取到IPv4地址：%s" % ipv4)
                    print("修改域名解析成功")
                else:
                    print("解析已存在、IPv4地址没变，解析不更新")
            elif domain_list['TotalCount'] > 1:
                request = DeleteSubDomainRecordsRequest()
                request.set_accept_format('json')
                request.set_DomainName(self.domain)
                request.set_RR(name)
                request.set_Type("A")
                response = self.client.do_action_with_exception(request)
                self.add(self.domain, name, "A", ipv4)
                print("获取到IPv4地址：%s" % ipv4)
                print("修改域名解析成功")
        else:
            print("IPv4解析未启用，如需使用将self.ipv4_flag值改为1")

    def ipv6_dns(self, name):
        """
        :param name: 解析到子域名
        :return:
        """

        global response
        if self.ipv6_flag == 1:
            request = DescribeSubDomainRecordsRequest()
            request.set_accept_format('json')
            request.set_DomainName(self.domain)
            request.set_SubDomain(name + '.' + self.domain)
            request.set_Type("AAAA")
            response = self.client.do_action_with_exception(request)  # 获取域名解析记录列表
            domain_list = json.loads(response)  # 将返回的JSON数据转化为Python能识别的

            ip = urlopen('https://api-ipv6.ip.sb/ip').read()  # 使用IP.SB的接口获取ipv6地址
            ipv6 = str(ip, encoding='utf-8')
            print("获取到IPv6地址：%s" % ipv6)

            if domain_list['TotalCount'] == 0:
                self.add(self.domain, name, "AAAA", ipv6)
                print("新建域名解析成功")
            elif domain_list['TotalCount'] == 1:
                if domain_list['DomainRecords']['Record'][0]['Value'].strip() != ipv6.strip():
                    self.update(domain_list['DomainRecords']['Record'][0]['RecordId'], name, "AAAA", ipv6)
                    print("修改域名解析成功")
                else:
                    print("IPv6地址没变，解析不更新")
            elif domain_list['TotalCount'] > 1:
                from aliyunsdkalidns.request.v20150109.DeleteSubDomainRecordsRequest import \
                    DeleteSubDomainRecordsRequest
                request = DeleteSubDomainRecordsRequest()
                request.set_accept_format('json')
                request.set_DomainName(self.domain)
                request.set_RR(name)
                request.set_Type("AAAA")
                response = self.client.do_action_with_exception(request)
                self.add(self.domain, name, "AAAA", ipv6)
                print("修改域名解析成功")
        else:
            print("IPv6解析未启用，如需使用将 self.ipv6_flag 值改为1")


if __name__ == '__main__':
    domain = "soliton.wang"
    ali_key = "ali_accessKeyId"
    ali_Secret = "ali_accessSecret"
    app = dns(Domain=domain, Ali_KeyId=ali_key, Ali_Secret=ali_Secret)
    app.ipv4_dns("www")
